<template>
  <div class="cropper_model">
    <el-dialog
      title="图片剪裁"
      width="800px"
      class="cropper_model_dlg"
      :visible.sync="dialogVisible"
      append-to-body
      :close-on-click-modal="false"
      :close-on-press-escape="false"
    >
      <div class="cropper_content">
        <div class="cropper" style="text-align: center;">
          <vueCropper
            ref="cropper"
            :img="options.img"
            :outputSize="options.outputSize"
            :outputType="options.outputType"
            :info="options.info"
            :canScale="options.canScale"
            :autoCrop="options.autoCrop"
            :autoCropWidth="autoCropWidth"
            :autoCropHeight="autoCropHeight"
            :fixed="options.fixed"
            :fixedBox="options.fixedBox"
            :fixedNumber="fixedNumber"
            @realTime="previewImg"
          >
          </vueCropper>
          <div class="cropper_btns">
            <el-button type="primary" @click="goUpload" size="mini">
              重新上传
            </el-button>
            <el-button
              @click="rotateLeft"
              icon="el-icon-refresh-left"
              size="mini"
              title="左旋转"
            >
            </el-button>
            <el-button
              @click="rotateRight"
              icon="el-icon-refresh-right"
              size="mini"
              title="右旋转"
            >
            </el-button>
            <el-button @click="changeScale(1)" size="mini" title="放大">
              +
            </el-button>
            <el-button @click="changeScale(-1)" size="mini" title="缩小">
              -
            </el-button>
          </div>
        </div>
        <div class="cropper_right">
          <h3>预览</h3>
          <!-- 预览 -->
          <div
            class="cropper_preview"
            :style="{
              width: preview.w + 'px',
              height: preview.h + 'px',
              overflow: 'hidden',
              margin: '5px'
            }"
          >
            <div :style="preview.div">
              <img :src="preview.url" :style="preview.img" alt="" />
            </div>
          </div>
          <div style="margin-top: 100px;">
            <el-button type="primary" @click="uploadImg" :loading="loading">
              确定上传
            </el-button>
          </div>
        </div>
      </div>
      <!-- <div slot="footer" class="dialog-footer">
        <el-button @click="downLoad('blob')">下载</el-button>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="uploadImg" :loading="loading">
          确认
        </el-button>
      </div> -->
    </el-dialog>
  </div>
</template>

<script>
import COS from 'cos-js-sdk-v5'
import $ from 'jquery'
import { VueCropper } from "vue-cropper";
export default {
  components: { VueCropper },
  props: {
    autoCropWidth:{
      type: Number,
      default: 120
    },
    autoCropHeight:{
      type: Number,
      default: 120
    },
    fixedNumber:{
      type: Array,
      default: [4,3]
    }
  },
  data() {
    return {
      dialogVisible: false,
      loading: false,
      options: {
        img: "", // 裁剪图片的地址
        outputSize: 1, // 裁剪生成图片的质量
        outputType: "png", // 裁剪生成图片的格式
        info: true, // 裁剪框的大小信息
        canScale: true, // 图片是否允许滚动缩放
        autoCrop: true, // 是否默认生成截图狂
        fixed: true, // 是否开启截图框宽高固定比例
        autoCropWidth: 160, // 默认生成截图框宽度
        autoCropHeight: 80, // 默认生成截图框高度
        fixedNumber: [2, 1], // 截图框的宽高比例
        full: false, // 是否输出原图比例的截图
        fixedBox: true, // 固定截图框大小 不允许改变
        canMove: true, // 上传图片是否可以移动
        canMoveBox: true, // 截图框能否拖动
        original: true, // 上传图片按照原始比例渲染
        centerBox: false, // 截图框是否被限制在图片里面
        high: false, // 是否按照设备的dpr输出等比例图片
        infoTrue: false, // true为展示真实输出图片宽高false展示看到的截图框宽高
        maximgSize: 100, // 限制图片最大宽度和高度
        enlarge: 1, // 图片根据截图框输出比例倍数
        mode: "contain" // 图片默认渲染方式(contain, cover, 100px, 100% auto)
      },
      preview: {},
       //--上传到腾讯cos
      Bucket: '',
      Region: '', /* 存储桶所在地域，必须字段 */
      CosAuth: null,
    };
  },
  methods: {
    open(data) {
      this.options.img = window.URL.createObjectURL(data);
      console.log(data);
      this.dialogVisible = true;
    },
    close(){
      this.dialogVisible = false;
    },
    // base64转图片文件
    dataURLtoFile(dataurl) {
      let arr = dataurl.split(",");
      let mime = arr[0].match(/:(.*?);/)[1];
      let bstr = atob(arr[1]);
      let len = bstr.length;
      let u8arr = new Uint8Array(len);
      while (len--) {
        u8arr[len] = bstr.charCodeAt(len);
      }
      return new Blob([u8arr], { type: mime });
    },
    boldToFile(Blob,fileName){
      Blob.lastModifiedDate = new Date();
			Blob.name = fileName;
			return Blob;
    },
    /* downLoad(type) {
      event.preventDefault();
      const aLink = document.createElement("a");
      if (type === "blob") {
        this.$refs.cropper.getCropBlob(data => {
          let downImg = window.URL.createObjectURL(data);
          aLink.download = "photo.png";
          aLink.href = downImg;
          aLink.click();
        });
      } else {
        this.$refs.cropper.getCropData(data => {
          let file = this.dataURLtoFile(data, "test");
          // let file = data
          aLink.href = file;
          aLink.click();
        });
      }
    }, */
    // 左旋转
    rotateLeft() {
      this.$refs.cropper.rotateLeft();
    },
    // 右旋转
    rotateRight() {
      this.$refs.cropper.rotateRight();
    },
    // 放大缩小
    changeScale(num) {
      num = num || 1;
      this.$refs.cropper.changeScale(num);
    },
    // 实时预览
    previewImg(data) {
      this.preview = data;
    },
    goUpload() {
      this.close()
      // this.$emit("upAgain");
    },
    // 上传图片
    uploadImg() {
      let self = this;
      self.loading = true;
      this.$refs.cropper.getCropData( async data => {
        let resfile = this.dataURLtoFile(data);
        let file = this.boldToFile(resfile,"photo.png")
        // 生成文件类型
        // self.loading = false;
        // this.$emit("getFile",resFile)
        let res2 = await this.uploadOssEnterprise({file})
        let url = "https://" + res2.Location
        this.$emit("backUrl",url)
        this.close()
        setTimeout(()=>{self.loading = false;},500) // 防抖
      });
    },
    //自定义上传，裁剪后调用
    getCosAuth1(callback){
      // var COS = require('cos-js-sdk-v5');
      let _this = this
      $.ajax({
        async: false,
        type: "GET",
        contentType: "application/json;charset=UTF-8",
        headers: {
          'Content-Type': 'application/json;charset=utf8',
        },
        url: process.env.VUE_APP_BASE_API + '/cos/getAuthorization',
        //后端接口返回临时秘钥信息
        data: null,
        //请求成功，这段是cos代码
        success: function (data) {
          if (!data) return console.error('credentials invalid');
          _this.Bucket = data.bucket
          _this.Region = data.region
          _this.CosAuth = ({
            TmpSecretId: data.tmpSecretId,
            TmpSecretKey: data.tmpSecretKey,
            XCosSecurityToken: data.sessionToken,
            // 建议返回服务器时间作为签名的开始时间，避免用户浏览器本地时间偏差过大导致签名错误
            StartTime: data.start_time, // 时间戳，单位秒，如：1580000000
            ExpiredTime: data.expiredTime, // 时间戳，单位秒，如：1580000900
          });

          callback()

        },
        //请求失败，包含具体的错误信息
        error: function(e) {
          console.log(e.status);
          console.log(e.responseText);
        }
      });
    },

    uploadOssEnterprise(fileObj){
      return new Promise((resolve, reject)=>{
        console.log('uploadOssEnterprise');
        console.log(fileObj);

          //重点，getAuthorization内部封装函数
          
          let getCosAuth2 = (options, callback) => {
            callback(this.CosAuth)
          }
        this.getCosAuth1(() => {
          var cos = new COS({
            getAuthorization: getCosAuth2//重点调用函数
          });
          var myDate = new Date();
          var ossPath = 'e2b/' + myDate.getFullYear() + "/" + (myDate.getMonth() + 1);
          // 获取文件后缀
          var pathArr = fileObj.file.name.split('.')
          //  随机生成文件名称
          var fileRandName = Date.now() + "" + parseInt(Math.random() * 1000)
          var fileName = fileRandName + '.' + pathArr[pathArr.length - 1]
          // 要提交的key
          var fileKey = ossPath + "/" + fileName;
          let formdata = {
            Bucket: this.Bucket,
            Region: this.Region,
            Key: fileKey,
            Body: fileObj.file,
            onTaskReady: function(tid) {
  
            },
            onHashProgress: function(progressData) {
  
            },
            onProgress: function(progressData) {
  
              if(fileObj.onProgress){
                fileObj.onProgress(progressData)
              }
            },
          }
          cos.putObject(formdata, function(err, data) {
  
            resolve(data)
            if (!err&&fileObj.onSuccess) {
              fileName = fileName.toLocaleLowerCase();
              //计算图片高度
              if (fileName.indexOf(".jpg") > 0 || fileName.indexOf(".jpeg") > 0 || fileName.indexOf(".png") > 0 || fileName
                .indexOf(".gif") > 0 || fileName.indexOf(".bmp") > 0) {
                var reader = new FileReader();
                reader.readAsDataURL(fileObj.file);
                reader.onload = function(theFile) {
                  var image = new Image();
                  image.src = theFile.target.result;
                  image.onload = function() {
                    fileObj.onSuccess({
                      src: "https://" + data.Location,
                      fileName: fileObj.file.name
                    })
                  };
                };
              } else {
                fileObj.onSuccess({
                  src: "https://" + data.Location,
                  fileName: fileObj.file.name,
                })
              }
            }
          });
        })
        
      })
    },
  }
};
</script>

<style lang="scss" scoped>
.cropper_model_dlg {
  .cropper_content {
    margin: 0 auto;
    width: 700px;
    height: 450px;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
  }
  .cropper {
    width: 400px;
    height: 400px;
    background: yellow;
  }
  .cropper_right {
    width: 300px;
    text-align: center;
  }
  .cropper_preview {
    margin: 0 auto;
    display: inline-block;
    border: 1px solid #ddd;
  }
  .cropper_btns {
    margin-top: 20px;
  }
}
</style>